home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 9 / FM Towns Free Software Collection 9.iso / t_os / tool / helper / src / dir.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-16  |  11.3 KB  |  565 lines

  1. /***********************************
  2.  
  3.     Dir & File Select
  4.  
  5. **********************************/
  6. #include    <stdio.h>
  7. #include    <stdlib.h>
  8. #include    <string.h>
  9. #include    <ctype.h>
  10. #include    <msdos.cf>
  11. #include    "dir.h"
  12. #include    "graphic.h"
  13.  
  14. #define TRUE        1
  15. #define FALSE        0
  16. #define ERR        (-1)
  17.  
  18. static struct {
  19.     unsigned char    dd_dmy[21];
  20.     unsigned char    dd_att;
  21.     unsigned short int    dd_time,dd_date;
  22.     unsigned long    dd_size;
  23.     char        dd_name[14];
  24. } dma;
  25.  
  26. extern int    errno;
  27.  
  28. char    *strdup();
  29.  
  30. static int dos_err_chk(void)
  31. {
  32.     if ( (Registers.Flags & 0x0001) != 0 ) {
  33.     errno = Registers.AX.R;
  34.     return ERR;
  35.     } else
  36.     return FALSE;
  37. }
  38. int    chdrv(int no)
  39. {
  40.     Registers.AX.R = 0x0E00;
  41.     Registers.DX.R = no;        /* A=0, B=1 ... */
  42.     calldos();
  43.     return dos_err_chk();
  44. }
  45. int    mkdir(char *name)
  46. {
  47.     Registers.AX.R = 0x3900;
  48.     Registers.DX.R = (int)name;
  49.     Registers.DS.R = getds();
  50.     calldos();
  51.     return dos_err_chk();
  52. }
  53. int    rmdir(char *name)
  54. {
  55.     Registers.AX.R = 0x3A00;
  56.     Registers.DX.R = (int)name;
  57.     Registers.DS.R = getds();
  58.     calldos();
  59.     return dos_err_chk();
  60. }
  61. int    chdir(char *name)
  62. {
  63.     Registers.AX.R = 0x3B00;
  64.     Registers.DX.R = (int)name;
  65.     Registers.DS.R = getds();
  66.     calldos();
  67.     return dos_err_chk();
  68. }
  69. int    getdrv(void)
  70. {
  71.     Registers.AX.R = 0x1900;
  72.     calldos();
  73.     if ( dos_err_chk() != 0 )
  74.     return ERR;
  75.     return (Registers.AX.R & 0xFF);    /* A=0, B=1 ... */
  76. }
  77. int    getdir(char *name)
  78. {
  79.     *(name++) = '\\';
  80.     Registers.AX.R = 0x4700;
  81.     Registers.DX.R = 0x0000;
  82.     Registers.SI.R = (int)name;
  83.     Registers.DS.R = getds();
  84.     calldos();
  85.     if ( dos_err_chk() )
  86.     *name = '\0';
  87.     return dos_err_chk();
  88. }
  89. int    getattr(char *name)
  90. {
  91.     Registers.AX.R = 0x4300;
  92.     Registers.DX.R = (int)name;
  93.     Registers.DS.R = getds();
  94.     calldos();
  95.     if ( dos_err_chk() )
  96.     return ERR;
  97.     return Registers.CX.R;
  98. }
  99. int    disk_free(int drv, unsigned long *fr, unsigned long *ta)
  100. {
  101.     unsigned long sz;
  102.  
  103.     Registers.AX.R = 0x3600;
  104.     Registers.DX.R = drv + 1;        /* A=0, B=1 ... */
  105.     calldos();
  106.  
  107.     if ( dos_err_chk() ||
  108.     (unsigned short)(Registers.AX.R) == 0xFFFF ||
  109.     (unsigned short)(Registers.DX.R) == 0 )
  110.     return ERR;
  111.  
  112.     sz = (unsigned short)(Registers.AX.R) *
  113.      (unsigned short)(Registers.CX.R);    /* byte */
  114.  
  115.     if ( sz > 1024UL ) {
  116.     *fr = (sz / 1024UL) * (unsigned short)(Registers.BX.R);
  117.     *ta = (sz / 1024UL) * (unsigned short)(Registers.DX.R);
  118.     } else {
  119.     *fr = (sz * (unsigned short)(Registers.BX.R)) / 1024UL;
  120.     *ta = (sz * (unsigned short)(Registers.DX.R)) / 1024UL;
  121.     }
  122.  
  123.     return FALSE;
  124. }
  125. int    drvsts(int no)
  126. {
  127.     Registers.AX.R = 0x4404;
  128.     Registers.BX.R = no + 1;        /* A=0, B=1 ...*/
  129.     Registers.CX.R = 0x0000;
  130.     calldos();
  131.     return (Registers.AX.R & 0x0E);
  132. }
  133. int    isdir(char *file)
  134. {
  135.     int     at;
  136.  
  137.     if ( (at = getattr(file)) == ERR )
  138.     return FALSE;
  139.  
  140.     return ((at & 0x10) != 0 ? TRUE:FALSE);
  141. }
  142. static char    *subname(register char *name)
  143. {
  144.     char    *p;
  145.  
  146.     if ( strcmp(name,".") == 0 ||
  147.      strcmp(name,"..") == 0 ||
  148.      (p = strrchr(name,'.')) == NULL )
  149.     while ( *name != '\0' ) name++;
  150.     else
  151.     name = p + 1;
  152.     return name;
  153. }
  154. static int     dir_cmp(DIRECT *sp,DIRECT *dp)
  155. {
  156.     int     cd;
  157.  
  158.     if ( IS_DIR(sp) != IS_DIR(dp) )
  159.     return IS_DIR(sp) ? ERR:TRUE;
  160.     if ( (cd = strcmp(subname(sp->d_name),subname(dp->d_name))) != 0 )
  161.     return cd;
  162.     return strcmp(sp->d_name,dp->d_name);
  163. }
  164. static DIRECT  *dir_sort(DIRECT *sp,DIRECT *dp)
  165. {
  166.     register DIRECT *tp;
  167.     DIRECT tmp;
  168.  
  169.     tp = &tmp;
  170.     if ( (tp->d_next = sp) == NULL )
  171.     return dp;
  172.     while ( tp->d_next != NULL ) {
  173.     if ( dir_cmp(tp->d_next,dp) >= 0 )
  174.         break;
  175.     tp = tp->d_next;
  176.     }
  177.     dp->d_next = tp->d_next;
  178.     tp->d_next = dp;
  179.     return tmp.d_next;
  180. }
  181. static DIRECT  *dir_apend(DIRECT *sp,DIRECT *dp)
  182. {
  183.     register DIRECT *tp;
  184.     DIRECT tmp;
  185.  
  186.     tp = &tmp;
  187.     if ( (tp->d_next = sp) == NULL )
  188.     return dp;
  189.     while ( tp->d_next != NULL )
  190.     tp = tp->d_next;
  191.     dp->d_next = tp->d_next;
  192.     tp->d_next = dp;
  193.     return tmp.d_next;
  194. }
  195. static DIRECT  *dir_get(char *dir,int sw)
  196. {
  197.     register DIRECT  *np;
  198.     DIRECT  *tp=NULL;
  199.  
  200.     Registers.AX.R = 0x1A00;
  201.     Registers.DX.R = (int)&dma;
  202.     Registers.DS.R = getds();
  203.     calldos(); 
  204.  
  205.     Registers.AX.R = 0x4E00;
  206.     Registers.CX.R = 0x31;
  207.     Registers.DX.R = (int)dir;
  208.     Registers.DS.R = getds();
  209.     calldos();
  210.  
  211.     if ( (Registers.Flags & 0x0001) != 0 )
  212.     return NULL;
  213.  
  214.     do {
  215.     if ( (sw == FALSE || (dma.dd_att & 0x10) != 0) &&
  216.          strcmp(dma.dd_name,".") != 0 ) {
  217.  
  218.         if ( (np = (DIRECT *)
  219.                malloc(sizeof(DIRECT)+strlen(dma.dd_name))) == NULL )
  220.         break;
  221.  
  222.         np->d_next = np->d_child = NULL;
  223.         np->d_att  = dma.dd_att;
  224.         np->d_time = dma.dd_time;
  225.         np->d_date = dma.dd_date;
  226.         np->d_size = dma.dd_size;
  227.         strcpy(np->d_name,dma.dd_name);
  228.         tp = dir_sort(tp,np);
  229.     }
  230.     Registers.AX.R = 0x4F00;
  231.     calldos();
  232.     } while ( (Registers.Flags & 0x0001) == 0 );
  233.  
  234.     return tp;
  235. }
  236.  
  237. /*******************************************
  238. static DIRECT  *dir_map(char *dir,int sw)
  239. {
  240.     FILE    *fp;
  241.     register DIRECT  *np;
  242.     DIRECT  *tp=NULL;
  243.     char    *p;
  244.     char    tmp[BUFSIZ];
  245.  
  246.     if ( (p = strchr(dir,'\\')) == NULL )
  247.     p = dir;
  248.  
  249.     if ( (p = strrchr(p,'.')) == NULL ||
  250.      strcmp(p,".QQQ") != 0 ||
  251.      (fp = fopen(dir,"r")) == NULL )
  252.     return dir_get(dir,sw);
  253.  
  254.     while ( fgets(tmp,BUFSIZ,fp) != NULL ) {
  255.     if ( (p = strchr(tmp,'\n')) != NULL )
  256.         *p = '\0';
  257.  
  258.     if ( tmp[0] == '\0' || tmp[0] == '#' )
  259.         continue;
  260.  
  261.     if ( (np = (DIRECT *)malloc(sizeof(DIRECT)+strlen(tmp))) == NULL )
  262.         break;
  263.  
  264.     np->d_next = np->d_child = NULL;
  265.     np->d_att  = 0;
  266.     strcpy(np->d_name,tmp);
  267.     tp = dir_apend(tp,np);
  268.     }
  269.  
  270.     fclose(fp);
  271.     return tp;
  272. }
  273. ************************************************/
  274.  
  275. DIR    *opendir(char *dir)
  276. {
  277.     DIR    *dirp;
  278.     DIRECT *np;
  279.  
  280.     if ( (dirp = (DIR *)malloc(sizeof(DIR))) != NULL )
  281.     dirp->dd_top = dirp->dd_now = np = dir_get(dir,FALSE);
  282.  
  283.     return dirp;
  284. }
  285. DIRECT    *readdir(DIR *dirp)
  286. {
  287.     DIRECT *np;
  288.  
  289.     if ( (np = dirp->dd_now) != NULL )
  290.     dirp->dd_now = np->d_next;
  291.     return np;
  292. }
  293. void    seekdir(DIR *dirp,int n)
  294. {
  295.     DIRECT *np;
  296.  
  297.     np = dirp->dd_top;
  298.     while ( n-- > 0 && np != NULL )
  299.     np = np->d_next;
  300.     dirp->dd_now = np;
  301. }
  302. int    countdir(DIR *dirp)
  303. {
  304.     int    i;
  305.     DIRECT *np;
  306.  
  307.     i = 0;
  308.     np = dirp->dd_top;
  309.     while ( np != NULL ) {
  310.     i++;
  311.     np = np->d_next;
  312.     }
  313.     return i;
  314. }
  315. void    closedir(DIR *dirp)
  316. {
  317.     DIRECT *np,*tp;
  318.  
  319.     np = dirp->dd_top;
  320.     while ( np != NULL ) {
  321.     tp = np->d_next;
  322.     free(np);
  323.     np = tp;
  324.     }
  325.     free(dirp);
  326. }
  327. unsigned long    sizedir(char *dir)
  328. {
  329.     DIRECT *np, *tp;
  330.     unsigned long sz = 0;
  331.  
  332.     np = dir_get(dir, FALSE);
  333.     while ( np != NULL ) {
  334.     if ( !IS_DIR(np) )
  335.         sz += np->d_size;
  336.     tp = np;
  337.     np = np->d_next;
  338.     free(tp);
  339.     }
  340.     return sz;
  341. }
  342. char    *joint_path(char *dir,char *file)
  343. {
  344.     int     n;
  345.     char    *p;
  346.  
  347.     if ( file[1] == ':' || file[0] == '\\' )
  348.     dir[0] = '\0';
  349.     else {
  350.         p = dir;
  351.         while ( *p != '\0' ) p++;
  352.         if ( p != dir && *(p-1) != ':' && *(p-1) != '\\' )
  353.         strcat(dir,"\\");
  354.     }
  355.     strcat(dir,file);
  356.     return dir;
  357. }
  358. char    *file_serch(char *dir,char *wild)
  359. {
  360.     DIR     *dirp;
  361.     DIRECT  *dp;
  362.     char    tmp[256];
  363.  
  364.     strcpy(tmp,dir);
  365.     joint_path(tmp,wild);
  366.  
  367.     if ( (dirp = opendir(tmp)) == NULL )
  368.     return NULL;
  369.  
  370.     if ( (dp = readdir(dirp)) == NULL ) {
  371.     closedir(dirp);
  372.     return NULL;
  373.     }
  374.  
  375.     strcpy(tmp,dir);
  376.     joint_path(tmp,dp->d_name);
  377.     closedir(dirp);
  378.  
  379.     return strdup(tmp);
  380. }
  381. /********************
  382.  
  383. DIRECT    *alldir(char *dir)
  384. {
  385.     DIRECT *tp;
  386.     DIRECT *np;
  387.     char   tmp[128];
  388.  
  389.     tp = np = dir_get(dir,TRUE);
  390.     while ( np != NULL ) {
  391.     if ( IS_DIR(np) ) {
  392.         sprintf(tmp,"%s\\%s",dir,np->d_name);
  393.         np->d_child = alldir(tmp);
  394.     }
  395.     np = np->d_next;
  396.     }
  397.     return tp;
  398. }
  399. void    allclose(DIRECT *np)
  400. {
  401.     DIRECT *tp;
  402.  
  403.     while ( np != NULL ) {
  404.     tp = np->d_next;
  405.     if ( IS_DIR(np) )
  406.         allclose(np->child);
  407.     free(np);
  408.     np = tp;
  409.     }
  410. }
  411.  
  412. typedef struct _DIRP {
  413.     struct _DIRP    *next;
  414.     char        *nes;
  415.     char        *dir;
  416. } DIRPTR;
  417.  
  418. char    *strdup(char *str);
  419.  
  420.        DIRPTR    *dir_top=NULL;
  421. static DIRPTR    *dir_btm=NULL;
  422.  
  423. void    dir_tree(char *nes,char *dir,DIRECT *np)
  424. {
  425.     DIRPTR  *dp;
  426.     char    *p,*s;
  427.  
  428.     for ( p = nes ; *p != '\0' ; p++ );
  429.     for ( s = dir ; *s != '\0' ; s++ );
  430.     while ( np != NULL ) {
  431.     sprintf(tmp,"%s\x1b%c\x1b\x95%s",nes,
  432.             (np->d_next == NULL ? '\x9A':'\x93'),np->d_name);
  433.     strcpy(p,np->d_next == NULL ? "   ":"\x1b\x96  ");
  434.     sprintf(s,"\\%s",np->d_name);
  435.     if ( (dp = (DIRPTR *)malloc(sizeof(DIRPTR))) != NULL ) {
  436.         dp->next = NULL;
  437.         dir_btm->next = dp;
  438.         dir_btm = dp;
  439.  
  440.         dp->nes = strdup(tmp);
  441.         dp->dir = strdup(dir);
  442.     }
  443.     dir_tree(nes,dir,np->child);
  444.     *p = '\0';
  445.     *s = '\0';
  446.     np = np->d_next;
  447.     }
  448. }
  449. void    chengdir(int drive)
  450. {
  451.     DIRECT *tp;
  452.     DIRPTR *np;
  453.     char   nes[128];
  454.     char   dir[128];
  455.  
  456.     sprintf(dir,"%c:",drive+'A');
  457.     tp = alldir(dir);
  458.  
  459.     if ( (np = dir_top) != NULL ) {
  460.     do {
  461.         dir_top = np->next;
  462.         free(np->nes);
  463.         free(np->dir);
  464.         free(np);
  465.         np = dir_top;
  466.     } while ( np != NULL );
  467.     }
  468.  
  469.     if ( (dp = (DIRPTR *)malloc(sizeof(DIRPTR))) != NULL ) {
  470.     sprintf(dir,"%c:\\",drive+'A');
  471.     strcpy(nes,"  ");
  472.     dir_top = dir_btm = dp;
  473.     dp->next = NULL;
  474.     dp->nes = strdup(dir);
  475.     dp->dir = strdup(dir);
  476.     dir_tree(nes,dir,tp);
  477.     }
  478.  
  479.     allclose(tp);
  480. }
  481.  
  482. ******************/
  483.  
  484. static    int    GETONE(char **str)
  485. {
  486.     int ch;
  487.     char *p;
  488.  
  489.     p = *str;
  490.     ch = (unsigned char)(*(p++));
  491.     if ( islower(ch) )
  492.     ch = toupper(ch);
  493.     else if ( iskanji(ch) && iskanji2(*p) )
  494.     ch = (ch << 8) | (unsigned char)(*(p++));
  495.     *str = p;
  496.     return ch;
  497. }
  498.  
  499. static  char    *wild_rang(wild, fc)
  500. char    *wild;
  501. int     fc;
  502. {
  503.     int     wc, ch;
  504.  
  505.     while ( *wild != '\0' ) {
  506.         wc = GETONE(&wild);
  507.  
  508.         if ( wc == ']' )
  509.             return NULL;
  510.  
  511.         if ( *wild == '-' ) {
  512.             wild++;
  513.             ch = GETONE(&wild);
  514.             if ( ch == ']' ) {
  515.                 if ( wc <= fc )
  516.                     goto ENDOF;
  517.             } else if ( ch == '\0' )
  518.                 return NULL;
  519.  
  520.             if ( wc <= fc && fc <= ch )
  521.                 goto ENDOF;
  522.  
  523.         } else if ( wc == fc )
  524.             goto ENDOF;
  525.     }
  526.     return NULL;
  527.  
  528. ENDOF:
  529.     while ( *wild != '\0' ) {
  530.         if ( *(wild++) == ']' )
  531.             return wild;
  532.     }
  533.     return NULL;
  534. }
  535. int     wild_mach(wild, file)
  536. char    *wild;
  537. char    *file;
  538. {
  539.     int     wc, fc;
  540.  
  541.     for ( ; ; ) {
  542.         wc = GETONE(&wild);
  543.         fc = GETONE(&file);
  544.  
  545.         if ( wc == '\0' )
  546.             return (fc == '\0' ? TRUE:FALSE);
  547.  
  548.         else if ( wc == '*' ) {
  549.             if ( *wild == '\0' )
  550.                 return TRUE;
  551.             for ( file-- ; *file != '\0' ; file++ ) {
  552.                 if ( wild_mach(wild, file) )
  553.                     return TRUE;
  554.             }
  555.             return FALSE;
  556.  
  557.         } else if ( wc == '[' ) {
  558.             if ( (wild = wild_rang(wild, fc)) == NULL )
  559.                 return FALSE;
  560.  
  561.         } else if ( wc != '?' && wc != fc )
  562.             return FALSE;
  563.     }
  564. }
  565.